package com.ukefu.webim.web.handler.api.rest;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.client.NettyClients;
import com.ukefu.webim.service.acd.ServiceQuene;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.AgentServiceRepository;
import com.ukefu.webim.service.repository.AgentStatusRepository;
import com.ukefu.webim.service.repository.AgentUserRepository;
import com.ukefu.webim.service.repository.OrganRepository;
import com.ukefu.webim.service.repository.UserRepository;
import com.ukefu.webim.util.MessageUtils;
import com.ukefu.webim.util.OnlineUserUtils;
import com.ukefu.webim.util.RestResult;
import com.ukefu.webim.util.RestResultType;
import com.ukefu.webim.util.router.OutMessageRouter;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.model.AgentService;
import com.ukefu.webim.web.model.AgentStatus;
import com.ukefu.webim.web.model.AgentUser;
import com.ukefu.webim.web.model.MessageOutContent;
import com.ukefu.webim.web.model.Organ;
import com.ukefu.webim.web.model.SessionConfig;
import com.ukefu.webim.web.model.TransMsg;
import com.ukefu.webim.web.model.User;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/api/agent")
@Api(value = "在线客服状态切换", description = "在线客服状态切换")
public class ApiAgentController extends Handler{

	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private OrganRepository organRes ;
	
	@Autowired
	private AgentStatusRepository agentStatusRepository ;
	
	@Autowired
	private AgentUserRepository agentUserRepository ;
	
	@Autowired
	private AgentServiceRepository agentServiceRepository;

	/**
	 * 新增或修改用户用户 ，在修改用户信息的时候，如果用户 密码未改变，请设置为 NULL
	 * @param request
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/status")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("在线客服状态切换")
    public ResponseEntity<RestResult> put(HttpServletRequest request , @Valid String status) {
    	if(!org.apache.commons.lang3.StringUtils.isBlank(status)){
    		User user = userRepository.findByIdAndOrgi(super.getUser(request).getId(), super.getOrgi(request)) ;
    		if("ready".equals(status)){
    			//切换到就绪
    			Organ organ = null ;
    			if(!StringUtils.isBlank(user.getOrgan())){
    				organ = organRes.findByIdAndOrgi(user.getOrgan(), super.getOrgiByTenantshare(request)) ;
    			}
    			if(OnlineUserUtils.ready(user, super.getOrgi(request), organ) == false){
    				ModelAndView view = request(super.createRequestPageTempletResponse("/public/error"));
    				view.addObject("msg","就绪坐席超过数量");
    			}
    		}else if("notready".equals(status)){
    			//切换到未就绪
    			if(user!=null) {
    				ServiceQuene.deleteAgentStatus(user.getId(), user.getOrgi(), "0".equals(user.getUsertype()));
    			}
    		}else if("busy".equals(status)){
    			//切换到忙碌
    			List<AgentStatus> agentStatusList = agentStatusRepository.findByAgentnoAndOrgi(user.getId() , super.getOrgi(request));
    			AgentStatus agentStatus = null ;
    	    	if(agentStatusList.size() > 0){
    	    		agentStatus = agentStatusList.get(0) ;
    				agentStatus.setBusy(true);
    				agentStatus.setStatus(UKDataContext.AgentStatusEnum.READY.toString());
    				ServiceQuene.recordAgentStatus(agentStatus.getAgentno(),agentStatus.getUsername(), agentStatus.getAgentno(), agentStatus.getSkill(), "0".equals(super.getUser(request).getUsertype()),agentStatus.getAgentno(), UKDataContext.AgentStatusEnum.READY.toString(), UKDataContext.AgentStatusEnum.BUSY.toString(), UKDataContext.AgentWorkType.MEIDIACHAT.toString() , agentStatus.getOrgi() , agentStatus.getUpdatetime() ,agentStatus.getSkill());
    				agentStatus.setUpdatetime(new Date());
    				agentStatusRepository.save(agentStatus);
    				CacheHelper.getAgentStatusCacheBean().put(agentStatus.getAgentno(), agentStatus, super.getOrgi(request));
    			}
    	    	ServiceQuene.publishMessage(super.getOrgi(request) , "agent" , "busy" , user.getId());
    	    	
    		}
    	}
        return new ResponseEntity<>(new RestResult(RestResultType.OK,status), HttpStatus.OK);
    }
	@RequestMapping(value = "/statf")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("邀请评价")
    public ResponseEntity<RestResult> statf(HttpServletRequest request ,@Valid String id) {
		AgentUser agentUser = agentUserRepository.findByIdAndOrgi(id, super.getOrgi(request)) ;
		if(agentUser!=null) {
			AgentService agentService = agentServiceRepository.findByIdAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request)) ;
			if(agentService!=null) {
				agentUser.setInvitevals(agentUser.getInvitevals()+1);
				agentUserRepository.save(agentUser) ;
				agentService.setInvite(true);
				agentService.setInvitedate(new Date());
				agentServiceRepository.save(agentService) ;	
			}
			OutMessageRouter router  = (OutMessageRouter) UKDataContext.getContext().getBean(agentUser.getChannel()) ;
			if(router!=null){
				MessageOutContent outMessage = new MessageOutContent() ;
				outMessage.setMessageType(UKDataContext.AgentUserStatusEnum.INVIT.toString());
				outMessage.setCalltype(UKDataContext.CallTypeEnum.IN.toString());
				outMessage.setCreatetime(UKTools.dateFormate.format(new Date()));
				outMessage.setAgentserviceid(agentUser.getAgentserviceid());
				SessionConfig sessionConfig = ServiceQuene.initSessionConfig(super.getOrgi(request)) ;
				if(!StringUtils.isBlank(sessionConfig.getSatisftext())) {
					String queneTip = "<span id='agentno'>"+agentService.getAgentusername()+"</span>" ;
					outMessage.setMessage(sessionConfig.getSatisftext().replaceAll("\\{agent\\}", queneTip));
				}
				
				router.handler(agentUser.getUserid(), UKDataContext.MessageTypeEnum.STATUS.toString(), agentUser.getAppid(), outMessage);
			}
		}
        return new ResponseEntity<>(new RestResult(RestResultType.OK), HttpStatus.OK);
    }
	@RequestMapping(value = "/end")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("结束对话")
	public ResponseEntity<RestResult> end(HttpServletRequest request ,@Valid String userid) throws Exception {
		AgentUser agentUser = agentUserRepository.findByIdAndOrgi(userid, super.getOrgi(request));
		if(agentUser!=null && super.getUser(request).getId().equals(agentUser.getAgentno())){
			AgentService agentService = agentServiceRepository.findByIdAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request)) ;
			if(agentService!=null) {
				agentUser.setInvitevals(agentUser.getInvitevals()+1);
				agentUserRepository.save(agentUser) ;
				agentService.setInvite(true);
				agentService.setInvitedate(new Date());
				agentServiceRepository.save(agentService) ;	
			}
			OutMessageRouter router  = (OutMessageRouter) UKDataContext.getContext().getBean(agentUser.getChannel()) ;
			if(router!=null){
				MessageOutContent outMessage = new MessageOutContent() ;
				outMessage.setMessageType(UKDataContext.AgentUserStatusEnum.INVIT.toString());
				outMessage.setCalltype(UKDataContext.CallTypeEnum.IN.toString());
				outMessage.setCreatetime(UKTools.dateFormate.format(new Date()));
				outMessage.setAgentserviceid(agentUser.getAgentserviceid());
				SessionConfig sessionConfig = ServiceQuene.initSessionConfig(super.getOrgi(request)) ;
				if(!StringUtils.isBlank(sessionConfig.getSatisftext())) {
					String queneTip = "<span id='agentno'>"+agentService.getAgentusername()+"</span>" ;
					outMessage.setMessage(sessionConfig.getSatisftext().replaceAll("\\{agent\\}", queneTip));
				}
				
				router.handler(agentUser.getUserid(), UKDataContext.MessageTypeEnum.STATUS.toString(), agentUser.getAppid(), outMessage);
			}
			
			ServiceQuene.deleteAgentUser(agentUser, super.getOrgi(request) , UKDataContext.EndByType.AGENT.toString());
			if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
				if(agentService!=null) {
					agentService.setStatus(UKDataContext.AgentUserStatusEnum.END.toString());
					agentServiceRepository.save(agentService) ;
				}
			}
		}
		return new ResponseEntity<>(new RestResult(RestResultType.OK), HttpStatus.OK);
	}
	@RequestMapping(value = "/transfer/save")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("转接坐席保存")
	public ResponseEntity<RestResult> transfer(HttpServletRequest request, @Valid String userid 
			, @Valid String agentserviceid, @Valid String agentuserid, @Valid String agentno, @Valid String skill , @Valid String memo) throws Exception {
		if(!StringUtils.isBlank(userid) && !StringUtils.isBlank(agentuserid) && !StringUtils.isBlank(agentserviceid)){
			AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(super.getUser(request).getId(), super.getOrgi(request)) ;
			List<AgentUser> agentUserList = agentUserRepository.findByUseridAndOrgi(userid, super.getOrgi(request))  ;
			AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(userid, super.getOrgi(request)) ;
			for(AgentUser temp : agentUserList) {
				if(agentUser!=null && !temp.getId().equals(agentUser.getId())) {
					agentUserRepository.delete(temp);
				}
			}
			AgentService agentService = this.agentServiceRepository.findByIdAndOrgi(agentserviceid, super.getOrgi(request)) ;
			if(agentUser != null){
				SessionConfig sessionConfig = ServiceQuene.initSessionConfig(super.getOrgi(request)) ;
				agentUser.setAgentno(null);
				if(!StringUtils.isBlank(skill)) {
					agentUser.setSkill(skill);
				}
				if(sessionConfig.isTranstip() && !StringUtils.isBlank(agentno)) {
					TransMsg transMsg = new TransMsg();
					if(!StringUtils.isBlank(sessionConfig.getTranstiptitle())) {
						transMsg.setTitle(MessageUtils.replaceMessage(agentUser , agentStatus , sessionConfig.getTranstiptitle()));
					}
					if(!StringUtils.isBlank(memo)) {
						transMsg.setMemo(memo);
					}else if(!StringUtils.isBlank(sessionConfig.getTranstipmsg())){
						transMsg.setMemo(MessageUtils.replaceMessage(agentUser , agentStatus, sessionConfig.getTranstipmsg()));
					}
					transMsg.setUserid(userid);
					transMsg.setName(super.getUser(request).getUname());
					transMsg.setUsername(super.getUser(request).getUsername());
					transMsg.setNickname(super.getUser(request).getNickname());
					transMsg.setTime(UKTools.simpleDateFormat.format(new Date()));
					if(sessionConfig.getTranstiptimeout() > 0) {
						transMsg.setTimeout(sessionConfig.getTranstiptimeout());
					}else {
						transMsg.setTimeout(5000);
					}
					agentUser.setStatus(UKDataContext.AgentUserStatusEnum.INTRANS.toString());
					agentUser.setTransfer(true);
					agentUser.setTransferagent(agentno);
					agentUser.setTransfertime(new Date(System.currentTimeMillis() + transMsg.getTimeout()));

					agentUserRepository.save(agentUser) ;
					CacheHelper.getAgentUserCacheBean().put(userid , agentUser , super.getOrgi(request)) ;
					
					NettyClients.getInstance().sendAgentEventMessage(agentno, UKDataContext.MessageTypeEnum.TRANS.toString(), transMsg);
				}else if(!StringUtils.isBlank(agentno)){
					AgentStatus transAgentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentno, super.getOrgi(request)) ;
					if(transAgentStatus!=null){
						agentUser.setAgentno(agentno);
						ServiceQuene.updateAgentStatus(transAgentStatus, agentUser, super.getOrgi(request), true);
						agentService.setAgentno(agentno);
						if(!StringUtils.isBlank(skill)) {
							agentService.setSkill(skill);
						}
						agentService.setAgentusername(transAgentStatus.getUsername());

						//推送转接提示
						if(!StringUtils.isBlank(agentUser.getUserid())){
							MessageOutContent outMessage = new MessageOutContent() ;
							outMessage.setMessage(ServiceQuene.getTransMessage(agentService , agentUser.getChannel(),super.getOrgi(request)));
							outMessage.setMessageType(UKDataContext.MediaTypeEnum.TEXT.toString());
							outMessage.setCalltype(UKDataContext.CallTypeEnum.IN.toString());
							if(agentStatus!=null) {
								outMessage.setNickName(agentStatus.getUsername());
							}
							outMessage.setCreatetime(UKTools.dateFormate.format(new Date()));
							OutMessageRouter router = null ; 
							router  = (OutMessageRouter) UKDataContext.getContext().getBean(agentUser.getChannel()) ;
							if(router!=null && sessionConfig != null && sessionConfig.isEnabletransmsg()){
								router.handler(agentUser.getUserid(), UKDataContext.MessageTypeEnum.STATUS.toString(), agentUser.getAppid(), outMessage);
							}
						}
					}
					agentService.setAgentno(agentno);
					agentUserRepository.save(agentUser) ;
					CacheHelper.getAgentUserCacheBean().put(userid , agentUser , super.getOrgi(request)) ;
					
					NettyClients.getInstance().sendAgentEventMessage(agentno, UKDataContext.MessageTypeEnum.NEW.toString(), agentUser);
				}else{
					/**
					 * 原会话结束
					 */
					agentService.setAgentservice(UKDataContext.AgentUserStatusEnum.END.toString());
					
					if(!StringUtils.isBlank(skill)) {
						agentUser.setSkill(skill);
					}else {
						agentUser.setSkill(null);
					}
					/**
					 * 避免受到“历史坐席优先分配”影响
					 */
					agentUser.setRefuse(true);
					agentUser.setTransfer(true);
					agentUser.setTransferagent(agentno);
					agentUser.setTransfertime(new Date());
					
					agentUser.setStatus(UKDataContext.AgentUserStatusEnum.INQUENE.toString());
					
					agentUserRepository.save(agentUser) ;
					CacheHelper.getAgentUserCacheBean().put(userid , agentUser , super.getOrgi(request)) ;
					
					AgentService newAgentService = ServiceQuene.allotAgent(agentUser, agentUser.getOrgi()) ;
					if(newAgentService!=null && UKDataContext.AgentUserStatusEnum.INSERVICE.toString().equals(newAgentService.getStatus())) {
						NettyClients.getInstance().sendAgentEventMessage(newAgentService.getAgentno(), UKDataContext.MessageTypeEnum.NEW.toString(), agentUser);
					}
				}
			}else{
				agentUser = agentUserRepository.findByIdAndOrgi(agentuserid, super.getOrgi(request));
				if(agentUser!=null){
					agentService.setAgentno(agentno);
					agentUserRepository.save(agentUser) ;
				}
			}
			
			if(agentService!=null){
				if(!StringUtils.isBlank(memo)){
					agentService.setTransmemo(memo);
				}
				agentService.setTrans(true);
				agentService.setTranstime(new Date());
				agentServiceRepository.save(agentService) ;
			}
			
			/**
			 * 放到最后处理，避免出现数据不一致的情况
			 */
			if(agentStatus!=null){
				ServiceQuene.updateAgentStatus(agentStatus, agentUser, super.getOrgi(request), false);
			}
		}
		return new ResponseEntity<>(new RestResult(RestResultType.OK), HttpStatus.OK);
	}
	
	@RequestMapping(value = "/getagentstatus")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("获取指定客服状态")
    public ResponseEntity<RestResult> getAgentStatus(HttpServletRequest request , @Valid String id) {
		AgentStatus agentStatus = null;
		if(!org.apache.commons.lang3.StringUtils.isBlank(id)){
    		agentStatus = (AgentStatus)CacheHelper.getAgentStatusCacheBean().getCacheObject(id, super.getOrgi(request));
    	}
        return new ResponseEntity<>(new RestResult(RestResultType.OK,agentStatus), HttpStatus.OK);
    }
}